/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bgate.core;

import com.bgate.game.MyMidlet;
import com.bgate.utils.KeyCodeAdapter;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;

/**
 *
 * @author user
 */
public abstract class MyGame extends GameCanvas implements Runnable {

    Screen screen;
    Thread gameThread;
    boolean isRunning;
    public static int delay;
    public boolean connect;
    public int key;

    public MyGame() {
        super(false);
        setFullScreenMode(true);
        delay = 50;
        start();
    }

    public int getScreenWidth() {
        return this.getWidth();
    }

    public int getScreenHeight() {
        return this.getHeight();
    }

    public int getDelay() {
        return delay;
    }

    public boolean isConnect() {
        return connect;
    }

    public void resume() {
        isRunning = true;
    }

    public void pause() {
        isRunning = false;
    }

    public void start() {
        gameThread = new Thread(this);
        gameThread.start();
        isRunning = true;
    }

    public void stop() {
        isRunning = false;
        gameThread = null;
    }

    public void setScreen(Screen screen) {
        isRunning = false;
        this.screen.pause();
        this.screen.dispose();
        this.screen = null;
        Runtime.getRuntime().gc();
        screen.resume();
        screen.update();
        this.screen = screen;
        isRunning = true;
    }

    public void setStartScreen(Screen screen) {
        this.screen = screen;
    }

    public Screen getCurrentScreen() {
        return screen;
    }

    public Graphics getGameGraphics() {
        return getGraphics();
    }

    public boolean isTouchHandler() {
        if (hasPointerEvents() && hasPointerMotionEvents()) {
            return true;
        }
        return false;
    }

    public boolean isNeedShowInputForm() {
        if (isTouchHandler() && this.getWidth() >= 320 && this.getHeight() >= 320) {
            return true;
        } else {
            return false;
        }
    }

    public void update() {
        try {
            screen.update();
        } catch (Exception ex) {
            ex.printStackTrace();
            return;
        }
    }

    public void present(Graphics g) {
        if (isRunning) {
            g.setColor(0x000000);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            try {
                screen.present(g);
            } catch (Exception ex) {
                ex.printStackTrace();
                return;
            }
        }
        g.setColor(0xff0000);
//        g.drawString("Phone Model : " + KeyCodeAdapter.getInstance().getFullPlatform(), 0, 0, Graphics.TOP | Graphics.LEFT);
        g.drawString("Memory : " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()), 0, 0, Graphics.TOP | Graphics.LEFT);
        g.drawString("Total : " + Runtime.getRuntime().totalMemory(), 0, Font.getDefaultFont().getHeight(), Graphics.TOP | Graphics.LEFT);
        g.drawString("Free Memory : " + Runtime.getRuntime().freeMemory(), 0, 2 * Font.getDefaultFont().getHeight(), Graphics.TOP | Graphics.LEFT);
        flushGraphics();
    }

    public void run() {
        int timeGc = 0;
        Graphics g = getGraphics();
        Thread currentThread = Thread.currentThread();
        while (currentThread == gameThread) {
            long startTime = System.currentTimeMillis();
            if (isShown()) {
                try {
                    if (isRunning) {
                        update();
                    }
                    present(g);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                timeGc += delay;
                if (timeGc >= 5000) {
                    Runtime.getRuntime().gc();
                    timeGc = 0; 
                }
            }
            long timeTake = System.currentTimeMillis() - startTime;
            if (timeTake < delay) {
                synchronized (this) {
                    try {
                        wait(delay - timeTake);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            } else {
                Thread.currentThread().yield();
            }
        }
    }

    protected void keyPressed(int keyCode) {
        key = keyCode;
        int instantkeyCode = KeyCodeAdapter.getInstance().adoptKeyCode(keyCode);
        switch (instantkeyCode) {
            case KeyCodeAdapter.LEFT_KEY:
                screen.leftKeyPressed();
                return;
            case KeyCodeAdapter.RIGHT_KEY:
                screen.rightKeyPressed();
                return;
            case KeyCodeAdapter.DOWN_KEY:
                screen.downKeyPressed();
                return;
            case KeyCodeAdapter.UP_KEY:
                screen.upKeyPressed();
                return;
            case KeyCodeAdapter.CENTER_KEY:
                screen.fireKeyPressed();
                return;
            case KeyCodeAdapter.SOFT_KEY_MIDDLE_INTERNET:
                screen.fireKeyPressed();
                return;
            case KeyCodeAdapter.SOFT_KEY_LEFT:
                screen.softKeyLeftPressed();
                return;
            case KeyCodeAdapter.SOFT_KEY_RIGHT:
                screen.softKeyRightPressed();
                return;
            default:
                this.keyCode = keyCode;
                screen.numberKeyPressed(keyCode);
                return;
        }
    }

    int keyCode;

    protected void keyRepeated(int keyCode) {
        int gameAct = getGameAction(keyCode);
        switch (gameAct) {
            case UP:
                screen.upKeytRepeated();
                return;
            case DOWN:
                screen.downKeyRepeated();
                return;
            case LEFT:
                screen.leftKeyRepeated();
                return;
            case RIGHT:
                screen.rightKeyRepeated();
                return;
        }
    }

    protected void keyReleased(int keyCode) {
        int gameAct = getGameAction(keyCode);
        switch (gameAct) {
            case UP:
                screen.upKeyRealeased();
                return;
            case DOWN:
                screen.downKeyRealeased();
                return;
            case LEFT:
                screen.leftKeyRealeased();
                return;
            case RIGHT:
                screen.rightKeyRealeased();
                return;
        }
    }

    protected void pointerPressed(int x, int y) {
        super.pointerPressed(x, y);
        screen.pointerPressed(x, y);
    }

    protected void pointerReleased(int x, int y) {
        super.pointerReleased(x, y);
        screen.pointerReleased(x, y);
    }

    protected void pointerDragged(int x, int y) {
        super.pointerDragged(x, y);
        screen.pointerDragged(x, y);
    }
}
